#include "profile.h"
#include "simmodel.h"
#include "ui_profile.h"
#include "Hydraulics.h"
#include <QtGui/QWidget>
#include <QTextCodec>
#include <vector>
#include <QSizePolicy>
#include <QFileDialog>
#include <QMessageBox>
#include <QSettings>
#include <QFileSystemModel>

using namespace hydraulics;
using namespace std;

profile::profile(QWidget* pwgt) 
	: QDialog(pwgt, Qt::WindowTitleHint | Qt::WindowSystemMenuHint)
{
	ui.setupUi(this);
	connect(ui.btnAccept, SIGNAL(clicked), this, SLOT(on_btnAccept_clicked));
	connect(ui.btnReject, SIGNAL(clicked), this, SLOT(on_btnReject_clicked));
	connect(ui.btnLoad, SIGNAL(clicked), this, SLOT(on_btnLoad_clicked));
	connect(ui.btnAddRow, SIGNAL(clicked), this, SLOT(on_btnAddRow_clicked));
	connect(ui.btnRemoveRow, SIGNAL(clicked), this, SLOT(on_btnRemoveRow_clicked));
	connect(ui.btnRefresh, SIGNAL(clicked), this, SLOT(on_btnRefresh_clicked));
	initGraph();
	//changes = false;
}

profile::~profile(){
/*  delete leg;
	delete grid;
	delete curve;*/
}

void profile::on_btnAccept_clicked(){
	accept();
}

void profile::on_btnReject_clicked(){
	int result = QMessageBox::information(this, "Close", 
		"Close the form? any unsaved data will be lost", 
		QMessageBox::Yes | QMessageBox::Default, 
		QMessageBox::No, 
		QMessageBox::Cancel | QMessageBox::Escape); 
	if (result == QMessageBox::Yes) 
		reject();
}

void profile::on_btnRefresh_clicked(){
	QVector<double> y, x;
	double length = 0;
	for(unsigned int i = 0; i < itemCoordinates.size(); i++){
		x.push_back(itemCoordinates[i]->data(0).toDouble());
		y.push_back(itemHeights[i]->data(0).toDouble());
		if(length < x[i]) length = x[i];
	}
	ui.lblPipeLength->setText("Pipe length: " + QString("%1").arg(length) + " m");
	ui.lblPointCount->setText("Point count: " + QString("%1").arg(x.size()));
	table_rowCountChanged();
	createGraph(y, x);
}

void profile::on_btnAddRow_clicked(){
	int i;
	i = ui.table->currentRow() + 1;
	ui.table->insertRow(i);
	itemCoordinates.insert(itemCoordinates.begin()+ i,new QTableWidgetItem);
	ui.table->setItem(i, 0, itemCoordinates[i]);
	itemHeights.insert(itemHeights.begin()+ i,new QTableWidgetItem);
	ui.table->setItem(i, 1, itemHeights[i]);
	table_rowCountChanged();
}

void profile::on_btnRemoveRow_clicked(){
	int i;
	i = ui.table->currentRow();
	ui.table->removeRow(i);
	itemCoordinates.erase(itemCoordinates.begin()+ i);
	itemHeights.erase(itemHeights.begin()+ i);
	table_rowCountChanged();
}

void profile::table_rowCountChanged(){
	QColor color;
	for (unsigned int i = 0; i < itemCoordinates.size(); i++){
		if (i%2) color.setRgb(222, 255, 222);	
		else color.setRgb(191, 255, 191);
		itemCoordinates[i]->setBackgroundColor(color);
		itemCoordinates[i]->setTextAlignment(2);
		itemHeights[i]->setBackgroundColor(color);
		itemHeights[i]->setTextAlignment(2);
	}
}

void profile::on_btnLoad_clicked(){
	vector<double> coordinates, heights;
	QString FileLoading = QFileDialog::getOpenFileName(this,"Open","c:/","File CSV(*.csv)");
	QFile file(FileLoading);
	if(file.open(QIODevice::ReadOnly)){
		QTextStream stream(&file);
		QString str = stream.readAll();
		QStringList list = str.split('\n');
		for (unsigned int i = 0; i < list.size(); i++)
			if (list[i].size()){
				QStringList row = list[i].split(";");
				for (unsigned int j = 0; j < row.size(); j++)
					if(row[j].toStdString() == "\r") row.removeAt(j);
				if (row.size() == 2){
					coordinates.push_back(row[0].toDouble());
					heights.push_back(row[1].toDouble());
				}else{
					QMessageBox::critical(this, "Error", "Error on line " + QString("%1").arg(i + 1), QMessageBox::Ok);	
					coordinates.clear();
					break;
				}
			}
		displayTableAndGraph(coordinates, heights);
	}

}
void profile::displayTableAndGraph(vector<double>coordinates, vector<double> heights){
	if(coordinates.size() == heights.size()){
		ui.table->clear();
		ui.table->setRowCount(coordinates.size());

		QStringList headerLabels;
		headerLabels.push_back("Coordinates");
		headerLabels.push_back("Heights");
		ui.table->setHorizontalHeaderLabels(headerLabels);
		itemCoordinates.resize(coordinates.size());
		itemHeights.resize(heights.size());
		QColor color;
		QVector<double> y, x;
		double length = 0;
		for (unsigned int i = 0; i < coordinates.size(); i++){
			itemCoordinates[i] = new QTableWidgetItem;
			QVariant tableCoordinates;
			tableCoordinates.setValue(coordinates[i]);
			itemCoordinates[i]->setData(Qt::EditRole, tableCoordinates);
			ui.table->setItem(i, 0, itemCoordinates[i]);
			itemHeights[i] = new QTableWidgetItem;
			QVariant tableHeights;
			tableHeights.setValue(heights[i]);
			itemHeights[i]->setData(Qt::EditRole, tableHeights);
			//itemHeights->setBackgroundColor(color);
			ui.table->setItem(i, 1, itemHeights[i]);
			y.push_back(heights[i]);
			x.push_back(coordinates[i]);
			if(length < x[i]) length = x[i];
		}
		ui.lblPipeLength->setText("Pipe length: " + QString("%1").arg(length) + " m");
		ui.lblPointCount->setText("Point count: " + QString("%1").arg(x.size()));
		table_rowCountChanged();
		createGraph(y, x);
	}else
		QMessageBox::critical(this, "Error", "Error in data", QMessageBox::Ok);	
}

void profile::initGraph(){
	ui.plot->setTitle(QString::fromLocal8Bit("Profile"));
	//grid
	grid = new QwtPlotGrid;
	grid->enableXMin(true);
	grid->setMajPen(QPen(Qt::black,0,Qt::DotLine));
	grid->setMinPen(QPen(Qt::gray,0,Qt::DotLine));
	grid->attach(ui.plot);
	//title
	ui.plot->setAxisTitle(QwtPlot::xBottom,QString::fromLocal8Bit("Coordinates, m"));
	ui.plot->setAxisTitle(QwtPlot::yLeft,QString::fromLocal8Bit("Heights, m"));
	//curve
	curve = new QwtPlotCurve(QString("profile"));
	curve->setRenderHint(QwtPlotItem::RenderAntialiased);
	curve->setPen(QPen(Qt::red));
	//marker
	QwtSymbol *symbol = new QwtSymbol();
	symbol->setStyle(QwtSymbol::Ellipse);
	symbol->setPen(QColor(Qt::black));
	symbol->setSize(4);
	curve->setSymbol(symbol);
}

void profile::createGraph(QVector<double>& y, QVector<double>& x){
	for (int i = x.size() - 1; i > 0; i--)
		for (int j = 0; j < i; j++)
			if (x[j] > x[j + 1]) {	
				std::swap(x[j], x[j + 1]);
				std::swap(y[j], y[j + 1]);
			}
	curve->setSamples(x, y);
	curve->attach(ui.plot);
	ui.plot->replot();
}

void profile::setData(const vector<vector<double>>& data) {
	displayTableAndGraph(data[0], data[1]);
}

pipeline_profile_t profile::getProfile() {
	vector<double> coordinates, heights;
	for(unsigned int i = 0; i < itemCoordinates.size(); i++){
		coordinates.push_back(itemCoordinates[i]->data(0).toDouble());
		heights.push_back(itemHeights[i]->data(0).toDouble());
	}
	for (unsigned int i = coordinates.size() - 1; i > 0; i--)
		for (unsigned int j = 0; j < i; j++)
			if (coordinates[j] > coordinates[j + 1]) {	
				std::swap(coordinates[j], coordinates[j + 1]);
				std::swap(heights[j], heights[j + 1]);
			}
	pipeline_profile_t pipeprofile;
	pipeprofile.coordinates = coordinates;
	pipeprofile.heights = heights;
	return pipeprofile;
}
